﻿using Bot.Domain.EndpointAPIResponseRecords;
using Bot.Domain.SessionChat;



using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bot.Domain.Report
{
    public enum EnumChatbotRateType
    {
        None = -1,
        Helpful = 0,
        NotHelpful = 1,
        NoRate=2
    }

    public class HighConfidenceResponseItem : BaseReportInfoItem
    {
        public int HighConfidence { get; set; }
        public int Helpful { get; set; }
        public int NotHelpful { get; set; }
        public int NoRate { get; set; }

        public override string GetValue(int i)
        {
            switch (i)
            {
                case 0:
                    return this.HighConfidence.ToString();
                    break;
                case 1:
                    return this.Helpful.ToString();
                    break;
                case 2:
                    return this.NotHelpful.ToString();
                    break;
                case 3:
                    return this.NoRate.ToString();
                    break;
                default:
                    return "";
            }
        }
    }
    public class HighConfidenceResponseInfo : BaseReportInfo<HighConfidenceResponseItem>
    {
        public int TotalHighConfidence { get; set; }
        public int TotalHelpful { get; set; }
        public int TotalNotHelpful { get; set; }
        public int TotalNoRate { get; set; }

        [JsonIgnore]
        public override List<string> FieldList
        {
            get
            {
                return new List<string>() {
                    "High Confidence","Helpful","Not Helpful","No Rate"
                };
            }
        }
        public override string GetValue(int i)
        {
            switch (i)
            {
                case 0:
                    return this.TotalHighConfidence.ToString();
                    break;
                case 1:
                    return this.TotalHelpful.ToString();
                    break;
                case 2:
                    return this.TotalNotHelpful.ToString();
                    break;
                case 3:
                    return this.TotalNoRate.ToString();
                    break;
                default:
                    return "";
            }
        }
    }
    public class HighConfidenceResponseEntityInfo
    {
        public IList<EndpointAPIResponseRecordsOutputDto> HighConfidenceResponseEntityList { get; set; }
    }

    public class HighConfidenceResponseWrap : BasicWrap<HighConfidenceResponseItem, HighConfidenceResponseInfo, HighConfidenceResponseEntityInfo>
    {
        
        public static HighConfidenceResponseInfo GetResponse(SearchCriteria search, HighConfidenceResponseEntityInfo entityInfo, bool ifEncode = true)
        {
            HighConfidenceResponseInfo result = new HighConfidenceResponseInfo();
            //UTCToLocal(ref entityInfo);
            switch (search.dimensionType)
            {
                case EnumDimensionType.ByTime://by time
                    result = GetInfoByTime(search, entityInfo, PushByTimeData, null, null);
                    break;
            }

            //watch.Stop();
            //System.Diagnostics.Debug.WriteLine("Calc Time: " + watch.Elapsed);

            return result;
        }

        //search the chat Source info for campaign by criteria
        private static HighConfidenceResponseInfo GetResponseByDimension(SearchCriteria search, HighConfidenceResponseEntityInfo entityInfo, bool ifEncode)
        {
            var result = new HighConfidenceResponseInfo();
            //result.dataType = EnumReportDataType.DataByDimension;
            //List<EndpointAPIResponseRecordsOutputDto> data = entityInfo.ResponseEntityList.Where(a=>a.CodePlanId == int.Parse(search.filterStr)).ToList();

            //result.TotalResponse = data.Count;
            //if (search.dimensionType == EnumDimensionType.ByDepartment)
            //{
            //    result.TotalAgentOnly = data.Count(a=>a.ChatType== (int)EnumChatType.AgentOnly);
            //    result.TotalChatbotOnly = data.Count(a => a.ChatType == (int)EnumChatType.ChatbotOnly);
            //    result.TotalFromBotToAgent = data.Count(a => a.ChatType == (int)EnumChatType.ChatbotToAgent);
            //}

            //result.dataList = new List<ResponseItem>();

            //foreach (var item in data)
            //{
            //    var newItem = new ResponseItem();
            //    newItem.tableRowName = GetTableRowName(ifEncode, item.RequestTime);
            //    newItem.fieldId = item.FieldId;
            //    newItem.chatCount = item.Response;
            //    newItem.chatPercentage = CalcPercent(item.Response, result.totalChatCount);
            //    if (search.dimensionType == EnumDimensionType.ByDepartment)
            //    {
            //        newItem.fromChatButtonCount = item.ChatButtons;
            //        newItem.fromChatButtonPercentage = CalcPercent(item.ChatButtons, result.totalFromChatButtonCount);
            //        newItem.fromManuallyInvitationCount = item.ManuallyInvitations;
            //        newItem.fromManuallyInvitationPercentage = CalcPercent(item.ManuallyInvitations, result.totalFromManuallyInvitationCount);
            //        newItem.fromAutoInvitationCount = item.AutoInvitations;
            //        newItem.fromAutoInvitationPercentage = CalcPercent(item.AutoInvitations, result.totalFromAutoInvitationCount);
            //    }

            //    newItem.startTime = search.startDate.ToString();
            //    newItem.startTimeDate = search.startDate;
            //    newItem.endTime = search.endDate.ToString();
            //    newItem.endTimeDate = search.endDate;
            //    result.dataList.Add(newItem);
            //}

            //result.dataList = result.dataList.OrderByDescending(o => o.Time).ToList();
            return result;
        }

        private static HighConfidenceResponseInfo PushByTimeData(HighConfidenceResponseInfo result, HighConfidenceResponseEntityInfo entityInfo, SearchCriteria search)
        {
            IEnumerable<EndpointAPIResponseRecordsOutputDto> ResponseEntityList = entityInfo.HighConfidenceResponseEntityList.OrderBy(c => c.CallTime);
            int lindex = 0;
            foreach (var item in ResponseEntityList)
            {
                Guid operatorId = Guid.Empty;
                operatorId = SessionHelper.GetSessionValue_CurrentOperatorId();
                item.CallTime = DateTimeHelper.UtcToLocal(item.CallTime, operatorId); 

                HighConfidenceResponseItem highConfidenceResponseItem = result.dataList[lindex];
                while (item.CallTime >= highConfidenceResponseItem.endTimeDate && lindex < result.dataList.Count)
                {
                    lindex++;
                    highConfidenceResponseItem = result.dataList[lindex];
                }
                highConfidenceResponseItem.HighConfidence++;
                result.TotalHighConfidence++;
                switch (item.RateType)
                {
                    case (int)EnumChatbotRateType.Helpful:
                        highConfidenceResponseItem.Helpful++;
                        result.TotalHelpful ++;
                        break;
                    case (int)EnumChatbotRateType.NotHelpful:
                        highConfidenceResponseItem.NotHelpful++;
                        result.TotalNotHelpful++;
                        break;
                    case (int)EnumChatbotRateType.NoRate:
                    case (int)EnumChatbotRateType.None:
                        highConfidenceResponseItem.NoRate++;
                        result.TotalNoRate++;
                        break;
                    default:
                        break;
                }
            }
            result.dataList = result.dataList.Reverse().ToList();
            GetListTotal(ref result, search);
            return result;
        }

        private static void GetListTotal(ref HighConfidenceResponseInfo result, SearchCriteria search)
        {
            double divNum = 0;
            if (search.timeUnit == EnumTimeIntervalType.Distribution24_7Hour)
            {
                divNum = GetWeeksInDateRange(search.startDate, search.endDate);
            }
            else if (search.timeUnit == EnumTimeIntervalType.Distribution48HalfHour)
            {
                divNum = GetDays(search.startDate, search.endDate);
            }
            else
            {
                result.TotalHighConfidence = result.TotalHighConfidence;
                result.TotalHelpful = result.TotalHelpful;
                result.TotalNotHelpful = result.TotalNotHelpful;
                result.TotalNoRate = result.TotalNoRate;
            }

            if (search.timeUnit == EnumTimeIntervalType.Distribution24_7Hour || search.timeUnit == EnumTimeIntervalType.Distribution48HalfHour)
            {
                result.TotalHighConfidence = result.TotalHighConfidence;
                result.TotalHelpful = result.TotalHelpful;
                result.TotalNotHelpful = result.TotalNotHelpful;
                result.TotalNoRate = result.TotalNoRate;
            }
        }

        #region export

        //search the New Export CSV Data for Chat Source Info by criteria
        public static NewExportCSVData GetExprotData(SearchCriteria search, HighConfidenceResponseEntityInfo entityInfo)
        {
            HighConfidenceResponseInfo info = GetResponse(search, entityInfo, false);
            NewExportCSVData result = new NewExportCSVData(string.Empty, new List<NewCSVColumn>(), new DataTable());
            switch (search.dimensionType)
            {
                case EnumDimensionType.ByTime://by time
                case EnumDimensionType.ByDepartment://by department
                case EnumDimensionType.ChatbotChats://by department
                case EnumDimensionType.ChatbotAnswers://by department
                case EnumDimensionType.ChatbotHightFidenceAnswers://by department
                    {
                        result = GetExprotCSVData(search, info, info.FieldList);
                        break;
                    }
                case EnumDimensionType.RequestPage:
                    {
                        result = GetExprotCSVData(search, info, new List<string>() { info.FieldList[0] });
                        break;
                    }
            }
            return result;
        }

        #endregion

    }
}
